package com.speed_run.service.impl;

import com.github.pagehelper.PageHelper;
import com.speed_run.dto.*;
import com.speed_run.global.GlobalMethod;
import com.speed_run.global.UserSession;
import com.speed_run.mapper.AdminMapper;
import com.speed_run.mapper.CircleMapper;
import com.speed_run.mapper.UserMapper;
import com.speed_run.model.Circle;
import com.speed_run.model.MomentCircle;
import com.speed_run.model.MomentComment;
import com.speed_run.model.MomentPics;
import com.speed_run.model.MomentVideo;
import com.speed_run.service.ICircleService;
import com.speed_run.utils.DistanceUtils;
import com.speed_run.utils.ImageUtils;
import com.speed_run.utils.ResponseEntity;
import com.speed_run.vo.circle.CircleVO;
import com.speed_run.vo.moment.MomentVo;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.*;

@Service
public class CircleServiceImpl implements ICircleService{

    @Autowired
    private CircleMapper cMapper;

    @Autowired
    private UserMapper userMapper;
    
	@Autowired
	private AdminMapper aMapper;
    
	@Value("${config.host}")
	private String host;
	
    @Override
    public ResponseEntity circleDetail(Integer circleId,Double lat, Double lng) {
        //TODO check circle状态
        CircleDTO dto = new CircleDTO();
        CircleVO circleVO = cMapper.circle(circleId);
        circleVO.setAvatar(host+circleVO.getAvatar());
        circleVO.setPic(host+circleVO.getPic());
        Integer count = cMapper.getCircleCountByUser(circleId, UserSession.get().getUserId());
        if(count == 0){
            circleVO.setIsFollowed(0);
        }
        List<UserCircleDTO> moment = setMoments(circleId,UserSession.get().getUserId(), new IndexDTO(),lat,lng);
        dto.setCirclDetail(circleVO);
        dto.setMoment(moment);
        return ResponseEntity.ok("success",dto);

    }

    @Override
    public ResponseEntity hostCircle() {
        List<CircleVO> vo = cMapper.hostCircles();
        List<Integer> ids = cMapper.getFollowCicleIds(UserSession.get().getUserId());
        for (CircleVO v: vo) {
    	   v.setAvatar(host+v.getAvatar());
           v.setPic(host+v.getPic());
            if(!ids.contains(v.getId())){
                v.setIsFollowed(0);
            }
        }
        return ResponseEntity.ok("success",vo);
    }

    @Override
    @Transactional
    public synchronized ResponseEntity followCircle(Integer id) {
        Integer count = cMapper.getCircleCountByUser(id,UserSession.get().getUserId());
        Circle circle = cMapper.getCircleById(id);
        if(count.equals(0)){
            cMapper.followCircle(id, UserSession.get().getUserId());
            circle.setNumber(circle.getNumber()+1);
            cMapper.updateCircle(circle);
        }else{
        	if(circle.getNumber() >0) {
        		cMapper.unFollowCircle(id, UserSession.get().getUserId());
                circle.setNumber(circle.getNumber()-1);
                cMapper.updateCircle(circle);
        	}
        }
        return ResponseEntity.ok("success");
    }

    @Override
    @Transactional
    public synchronized ResponseEntity unFollowCircle(Integer id) {
    	Circle circle = cMapper.getCircleById(id);
        cMapper.unFollowCircle(id, UserSession.get().getUserId());
        circle.setNumber(circle.getNumber()-1);
        cMapper.updateCircle(circle);
        return ResponseEntity.ok("success");
    }

    @Override
    public ResponseEntity getUserCircle(String userId) {
        List<CircleVO> list = cMapper.getUserCircle(userId);
        for (CircleVO vo: list) {
            vo.setAvatar(host+vo.getAvatar());
        }
        return ResponseEntity.ok("success",list);
    }

    @Override
    @Transactional
    public ResponseEntity circle(MultipartFile framePic, MultipartFile video , MultipartFile[] album , MomentVo vo) {
        vo.setUserId(UserSession.get().getUserId());
        vo.setUpdateDate(new Date());
        handleMoment(vo);
        saveMomentCircles(vo.getCircleIds(),vo.getId());
        if(framePic != null){
            MomentVideo v = new MomentVideo();
            handleVideo(framePic,video,vo,v);
            v.setMomentId(vo.getId());
            cMapper.saveMomentVideo(v);
        }else{
            List<MomentPics> p = new ArrayList<>();
            handleAlbum(album,vo,p,vo.getId());
            if(!p.isEmpty()){ 
                cMapper.saveMomentPics(p);
            }
        }
        return ResponseEntity.ok("success");
    }

    private void saveMomentCircles(String circleIds,Integer id) {
        if(!StringUtils.isEmpty(circleIds)){
            List<MomentCircle> list = new ArrayList<>();
            String[] cIds = circleIds.split(",");
            for (String cId:
                 cIds) {
                MomentCircle m = new MomentCircle();
                m.setMomentId(id);
                m.setCircleId(Integer.valueOf(cId));
                list.add(m);
            }
            if(!list.isEmpty()){
                cMapper.saveMomentCircles(list);
            }
        }
    }

    private void handleMoment(MomentVo vo) {
        cMapper.saveMoment(vo);
    }

    private void handleVideo(MultipartFile framePic, MultipartFile video, MomentVo vo,MomentVideo v) {
    	if(framePic == null) return;
        String picName = framePic.getOriginalFilename().toLowerCase();
        String videoName = video.getOriginalFilename().toLowerCase();
        try {
            String relativePath = GlobalMethod.getRelativePath(picName.substring(picName.lastIndexOf(".")).split("\\.")[1],"frame");
            String filePath = GlobalMethod.getFilepath(relativePath);
            File frameFile = new File(filePath);
            frameFile.createNewFile();
            framePic.transferTo(frameFile);
            v.setFramePic(relativePath);
            relativePath = GlobalMethod.getRelativePath(videoName.substring(videoName.lastIndexOf(".")).split("\\.")[1],"video");
            filePath = GlobalMethod.getFilepath(relativePath);
            v.setVideo(relativePath);
            File videoFile = new File(filePath);
            videoFile.createNewFile();
            video.transferTo(videoFile);
        }catch (Exception e){
        	e.printStackTrace();
        }
    }

    private void handleAlbum(MultipartFile[] album, MomentVo vo,List<MomentPics> p, Integer id) {
    	if(album == null) return;
        for(MultipartFile file :album) {
            String fileName = file.getOriginalFilename().toLowerCase();
            String relativePath = GlobalMethod.getRelativePath(fileName.substring(fileName.lastIndexOf(".")).split("\\.")[1],"pic");
            String filepath = GlobalMethod.getFilepath(relativePath);
            MomentPics pic = new MomentPics();
            try {
                File avatorFile = new File(filepath);
                avatorFile.createNewFile();
                file.transferTo(avatorFile);
                String zipFilePath = filepath.substring(0,filepath.lastIndexOf("."));
                zipFilePath = zipFilePath + "pre.jpg";
                ImageUtils.reduceImg(filepath,zipFilePath,100,100,null);
                pic.setMomentId(id);
                pic.setPic(relativePath);
                p.add(pic);
            }catch (IOException e){
                e.printStackTrace();
                p = new ArrayList<>() ;
            }
        }
    }

    @Override
    public ResponseEntity getUserCircleContent() {
        return null;
    }

    @Override
    public ResponseEntity deleteCircle(Integer id, String UserId) {
        cMapper.delMoment(id,UserId);
        return ResponseEntity.ok("删除成功");
    }


    @Override
    public ResponseEntity likeCirlce(Integer circleId) {
        Integer count = cMapper.findCircleLike(circleId,UserSession.get().getUserId());
        if(count == 0){
            cMapper.saveLike(circleId,UserSession.get().getUserId(),new Date());
        }else {
            cMapper.delLike(circleId,UserSession.get().getUserId());
        }
        return ResponseEntity.ok("success");
    }

    @Override
    @Transactional
    public ResponseEntity commentAdd(CommentVo vo) {
        vo.setUserId(UserSession.get().getUserId());
        CommnetDTO dto = new CommnetDTO();
        dto = dto.convertDTO(vo);
        cMapper.saveComment(dto);
        MomentComment mc = new MomentComment();
        mc.setId(dto.getId());
        mc.setContent(dto.getContent());
        mc.setCanDeleted(true);
        mc.setReviewer(dto.getUserId());
        mc.setReviewerName(userMapper.getUserByUserId(vo.getUserId()).getNickName());
        mc.setToUser(dto.getToUserId());
        mc.setMomentId(dto.getMomentId());
        mc.setToUserName(StringUtils.isEmpty(vo.getToUserId())?"":userMapper.getUserByUserId(vo.getToUserId()).getNickName());
        mc.setDate(vo.getCreateDate());
        return ResponseEntity.ok("回复成功",mc);
    }

    @Override
    @Transactional
    public ResponseEntity delComment(Integer id) {
        cMapper.delComment(id,UserSession.get().getUserId());
        return ResponseEntity.ok("删除成功");
    }

    @Override
    public ResponseEntity indexCircle(Double lat, Double lng) {
        IndexDTO  dto = new IndexDTO();
        setBannerPics(dto);//设置圈子首页banner图片
        setHotCircles(dto);//设置热门圈子
        setMoments(null,null,dto,lat,lng);//设置圈子列表内容
        return ResponseEntity.ok("获取圈子信息成功",dto);
    }

    private void setBannerPics(IndexDTO dto){
        //TODO 获取圈子BANNER123
        List<Map<String,Object>> data = aMapper.getFocusImgs();
        List<String> img = new ArrayList();
        for (int i = 0; i < data.size(); i++) {
        	 img.add(data.get(i).get("path").toString());
        }
        dto.setBannerPic(img);
    }


    private void setHotCircles(IndexDTO dto){
        List<HotCircleDTO> hotCircle = cMapper.hotCircleTop5();
        for (HotCircleDTO hotCircleDTO : hotCircle) {
        	hotCircleDTO.setAvatar(host+hotCircleDTO.getAvatar());
		}
        dto.setHotCircle(hotCircle);
    }

    @Override
    public List<UserCircleDTO> setMoments(Integer circleId,String userId, IndexDTO dto,Double lat,Double lng){
        PageHelper.startPage(1, 10);
        List<UserCircleDTO> moment = null;
        if(StringUtils.isEmpty(userId)){
            moment = cMapper.getHotMoment(UserSession.get().getUserId());
        }else if(circleId != null){
            moment = cMapper.getCircleDetailMoment(circleId, userId);
        }
        else {
             moment = cMapper.getUserMoment(userId);
        }
        for (UserCircleDTO d: moment) {
            List<MomentComment> m = cMapper.getMomentComment(d.getId(), StringUtils.isEmpty(userId)?UserSession.get().getUserId():userId);
            Integer distance = 0;
            if(lat == null || d.getLat() == null){
                distance = 0;
            }else {
                distance = (int)Math.ceil(DistanceUtils.getShortDistance(lng,lat,d.getLng(),d.getLat()));
            }
            List<String> pic = cMapper.getMomentPic(d.getId());
            List<String> _pic = new ArrayList<String>();
            VideoDTO video = cMapper.getVideo(d.getId());
            for (String s : pic) {
				String _s = host+s;
				_pic.add(_s);
			}
            if(video != null){
            	video.setFramePic(host+video.getFramePic());
            	video.setVideoUrl(host+video.getVideoUrl());
            }
            if(d.getFollowedNum() >0){
                d.setIsFollowed(true);
            }
            if(d.getLikedNum() >0){
                d.setIsLiked(true);
            }
            if(d.getUserId().equals(UserSession.get().getUserId())){
            	d.setCanDeleted(true);
            }
            d.setAvatar(host+d.getAvatar());
            //d.setComments(m);
            d.setCommentCount(m.size());
            d.setDistance(distance);
            d.setVideo(video);
            d.setAlbum(_pic);
        }
        dto.setMoment(moment);
        return  moment;
    }

    @Data
    class CommentAddDTO{
        private Integer id;
        private String userId;
        private String content;
        private Integer canDelete = 1;
    }

	@Override
	public ResponseEntity momentByPage(Integer type,String typeId, String userId,Integer page,Double lat,Double lng) {
        PageHelper.startPage(page, 10);
        if(type == null){
            type = 0;
        }
        List<UserCircleDTO> moment = new ArrayList<>();
        if(type.equals(0)){
            moment = cMapper.getHotMoment(UserSession.get().getUserId());
        }else if(type.equals(1)){
            moment = cMapper.getMoment(UserSession.get().getUserId());
        }else if(type.equals(3)){
            moment = cMapper.getCircleDetailMoment(Integer.valueOf(typeId),UserSession.get().getUserId());
        }else if (type.equals(4)){
            moment = cMapper.getUserFollowMoment(UserSession.get().getUserId());
        }
        else {
            moment =  cMapper.getUserMoment(typeId);
        }
        for (UserCircleDTO d: moment) {
        	 //List<MomentComment> m = cMapper.getMomentComment(d.getId(), UserSession.get().getUserId());
            Integer distance = 0;
        	 if(lat == null || d.getLat() == null){
                 distance = 0;
             }else {
                 distance = (int)Math.ceil(DistanceUtils.getShortDistance(lng,lat,d.getLng(),d.getLat()));
             }
             List<String> pic = cMapper.getMomentPic(d.getId());
             List<String> _pic = new ArrayList<String>();
             VideoDTO video = cMapper.getVideo(d.getId());
             for (String s : pic) {
 				String _s = host+s;
 				_pic.add(_s);
 			}
             if(video != null){
             	video.setFramePic(host+video.getFramePic());
             	video.setVideoUrl(host+video.getVideoUrl());
             }
             if(d.getUserId().equals(UserSession.get().getUserId())){
             	d.setCanDeleted(true);
             }
             d.setAvatar(host+d.getAvatar());
             //d.setComments();
             d.setCommentCount(0);
             d.setDistance(distance);
             d.setVideo(video);
             d.setAlbum(_pic);
            if(d.getFollowedNum() >0){
                d.setIsFollowed(true);
            }
            if(d.getLikedNum() >0){
                d.setIsLiked(true);
            }
        }
        return ResponseEntity.ok1("获取圈子信息成功",moment);
	}

    @Override
    @Transactional
    public ResponseEntity userFollower(String userId) {
        Integer count = userMapper.getFollowed(userId,UserSession.get().getUserId());
        if(count.equals(0)){
            cMapper.userFollower(userId,UserSession.get().getUserId());
        }else{
            cMapper.delFollower(userId,UserSession.get().getUserId());
        }
        return ResponseEntity.ok("操作成功");
    }

    @Override
    public ResponseEntity delFollower(String userId) {
        cMapper.delFollower(userId,UserSession.get().getUserId());
        return ResponseEntity.ok("取消关注成功");
    }

    @Override
    public ResponseEntity getMyFollowers() {
    	List<FollowerDTO> result = cMapper.getMyFollowers(UserSession.get().getUserId());
        List<FollowerDTO> _result = cMapper.getMyFollow(UserSession.get().getUserId());
        Set<String> ids = new HashSet<>();
        for (FollowerDTO dto:_result) {
            ids.add(dto.getUserId());
        }
        for (FollowerDTO dto : result) {
    		dto.setAvatar(host+dto.getAvatar());
    		if(!ids.contains(dto.getUserId())){
    		    dto.setIsFollowing(false);
            }
		}
        return ResponseEntity.ok2("success",result);
    }

    @Override
    public ResponseEntity getMyFollow() {
    	List<FollowerDTO> result = cMapper.getMyFollow(UserSession.get().getUserId());
    	//List<CircleVO> list = cMapper.getUserCircle(UserSession.get().getUserId());
    	for (FollowerDTO dto : result) {
    		dto.setAvatar(host+dto.getAvatar());
		}
    	 /*for (CircleVO vo: list) {
             vo.setAvatar(host+vo.getAvatar());
         }
    	Map<String, Object> data = new HashMap<>();
     	data.put("user", result);
     	data.put("circle", list);*/
        return ResponseEntity.ok("success",result);
    }

	@Override
	public ResponseEntity getUserMomentDetail(Integer momentId,Double lng, Double lat) {
		UserCircleDetailDTO d = cMapper.getUserCircleDetail(momentId,UserSession.get().getUserId());
    	List<MomentComment> m = cMapper.getMomentComment(d.getId(), UserSession.get().getUserId());
        Integer distance = 0;
    	 if(d.getLng() == null || d.getLat() == null){
             distance = 0;
         }else {
             distance = (int)Math.ceil(DistanceUtils.getShortDistance(lng,lat,d.getLng(),d.getLat()));
         }
         List<String> pic = cMapper.getMomentPic(d.getId());
         List<String> _pic = new ArrayList<String>();
         VideoDTO video = cMapper.getVideo(d.getId());
         for (String s : pic) {
			String _s = host+s;
			_pic.add(_s);
		}
         if(video != null){
         	video.setFramePic(host+video.getFramePic());
         	video.setVideoUrl(host+video.getVideoUrl());
         }
         if(d.getUserId().equals(UserSession.get().getUserId())){
         	d.setCanDeleted(true);
         }
         d.setAvatar(host+d.getAvatar());
         d.setComments(m);
         d.setCommentCount(m.size());
         d.setDistance(distance);
         d.setVideo(video);
         d.setAlbum(_pic);
        if(d.getFollowedNum() >0){
            d.setIsFollowed(true);
        }
        if(d.getLikedNum() >0){
            d.setIsLiked(true);
        }
        List<UserAvatarDTO> likeUser = cMapper.getUserAvatar(momentId);
		d.setLikeUser(likeUser);
		return ResponseEntity.ok("success",d);
	}
}
